{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1 引言"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线性回归算法应该是大多数人机器学习之路上的第一站，因为线性回归算法原理简单清晰，但却囊括了拟合、优化等等经典的机器学习思想。去年毕业时参加求职面试就被要求介绍线性回归算法，但由于当初过于追求神经网络、SVN、无监督学习等更加高大尚的算法，反而忽略了线性回归这些基础算法，当时给出的答案实在是差强人意。\n",
    "\n",
    "这一篇关于线性回归的总结我也犹豫过要不要写，如果你看了我上两篇关于最小二乘和梯度下降算法介绍的博客，你就会发现，关于最小二乘法和梯度下降算法的介绍都是以线性回归为例展开，所以，综合来说，之前两篇博客对一元线性回归还是多元线性回归算法都已经有了还算全面的总结，再写一篇关于线性回归的文章总感觉有些多余。不过，为了让我对机器学习的总结更加系统，还是决定专门总结一下。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2 什么是线性回归"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "说到线性回归，我们得先说说回归与分类、线性与非线性这些概念的区别。\n",
    "\n",
    "回归和分类都是有监督学习（机器学习分有监督学习和无监督学习）中的概念。从算法的目标或者作用上看，分类的目标就如同字面上的意思，就是分类，将数据分门别类，而且类别是有限的（数学上称为离散的）。但回归算法不同，回归算法的目标是预测，说详细些就是从已有数据和结果中获取规律，对其它数据的位置结果进行预测，预测结果的数量数无限的（数学上叫连续的）。举个例子我们可以根据楼房的建材、面积、用途将茅草房、普通住房、厂房等等有限的几类，这就是分类；另外，我们可以根据房屋面积、地段、装修等因素对楼房房价进行预测，预测结果有无限种可能，可能是10000元/平米，也能是10001.1元/平米——这就是回归的过程。\n",
    "\n",
    "对于线性和非线性的解释，我至今还没有见到过一个让我觉得满意的数学定义，所以，我也从直观认识上说说我的看法。我们高中时学习函数就是从一元一次函数学起的，一元一次函数在数学上可以表示为："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$f(x)={{\\theta }_{0}}+{{\\theta }_{1}}x$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在二维坐标轴上，其表现为一条直线。如果是三维空间中的二元一次函数，数学上表示为："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$f(x)={{\\theta }_{0}}+{{\\theta }_{1}}{{x}_{1}}+{{\\theta }_{2}}{{x}_{2}}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其在空间上图形为一平面。以此类推，在更高维（$n$维)的平面上，多元一次函数表达式为："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$f(x)={{\\theta }_{0}}+{{\\theta }_{1}}{{x}_{1}}+{{\\theta }_{2}}{{x}_{2}}+\\ldots +{{\\theta }_{n}}{{x}_{n}}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在多维空间上，其图形我们称为为超平面。\n",
    "\n",
    "如果一个数据模型能够用上述二维直线、三维平面或者更多维空间上的超平面去拟合，我们就可以说这个模型是线性模型。\n",
    "\n",
    "最后，综合上面内容总结一下什么是西安线性回归：\n",
    "\n",
    "**线性回归（Linear Regression）是一种通过属性的线性组合来进行预测的回归模型，其目的是找到一条直线或者一个平面或者更高维的超平面，使得预测值与真实值之间的误差最小化。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3 最优解"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面提到，线性回归的目的就是找到一个线性模型，使的预测值与真实值之间的误差最小，这就是一个优化的问题。为什么要优化呢？看看下图："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![image]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "正如你眼前所见，图中的点代表数据，能够对这些数据点进行大概拟合的直线不止一条，到底哪一条才是最好呢？以上图中数据为例，假设此时模型为${y}'=f(x)={{\\theta }_{0}}+{{\\theta }_{1}}{{x}_{1}}$，图像如下所示，我们要对其拟合程度进行评价："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![image]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "点$A({{x}_{i}},{{y}_{i}})$为数据集中某一点，使用模型预测时，结果为${A}'({{x}_{i}},{{{{y}'}}_{i}})$。我们用高中时学过，对于${A}$与${A}'$之间的误差，我们可以用它们之间的欧氏距离的平方来表示："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$E(A,{A}')={{({{x}_{i}}-{{x}_{i}})}^{2}}+{{({{y}_{i}}-{{y}_{i}})}^{2}}={{({{\\theta }_{0}}+{{\\theta }_{1}}{{x}_{i}}-{{y}_{i}})}^{2}}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这是对一个点的拟合程度评价，但数据集中可不止$A({{x}_{i}},{{y}_{i}})$一个数据点，所以，我们需要对每个点进行误差评估，然后求和，也就是误差平方和作为这个线性模型对数据集的总体拟合程度评估："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$J({{\\theta }_{0}},{{\\theta }_{1}})=\\sum\\limits_{i=1}^{m}{{{({{\\theta }_{0}}+{{\\theta }_{1}}{{x}_{i}}-{{y}_{i}})}^{2}}}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们将$J({{\\theta }_{0}},{{\\theta }_{1}})$成为损失函数，也有资料中称为目标函数。这里，${{\\theta }_{0}},{{\\theta }_{1}}$是模型中$x$的参数。在不同的模型中，${{\\theta }_{0}},{{\\theta }_{1}}$取不同值，我们要做的就是求目标函数$J({{\\theta }_{0}},{{\\theta }_{1}})$取最小值时的${{\\theta }_{0}},{{\\theta }_{1}}$确切值，换句话说就是求$J({{\\theta }_{0}},{{\\theta }_{1}})$的最优解问题。\n",
    "\n",
    "关于求最优解问题，最常用的算法就是最小二乘法和梯度下降法，这两种方法在前两篇博文中都有详细介绍，如果你尚不清楚其中原理和过程，还是去看看吧，这很重要，也很基础。\n",
    "\n",
    "上面说的是一元线性回归模型，对于多元线性回归模型，原理也是一样的，只不过需要求解的参数不止${{\\theta }_{0}},{{\\theta }_{1}}$两个了就是，这里不再多说。下面我们用代码实现一元线性回归模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4 代码实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4.1 pytorch实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在实现模型之前，首先我们要制造一个数据集，在[0, 10]区间范围内，随机生成100个数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.0000],\n",
      "        [0.1010],\n",
      "        [0.2020],\n",
      "        [0.3030],\n",
      "        [0.4040],\n",
      "        [0.5051],\n",
      "        [0.6061],\n",
      "        [0.7071],\n",
      "        [0.8081],\n",
      "        [0.9091]])\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "from torch.autograd import Variable\n",
    "from torch import nn\n",
    "import matplotlib.pyplot as plt\n",
    "x = torch.unsqueeze(torch.linspace(0, 10, 100), dim=1)\n",
    "print(x[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出的内容有100行，这就是一个列向量，我们以则100个数作为数据集中的自变量，也就是X，假设我们需要拟合的模型为：$y=f(x)=0.5x+15$，为了更加符合真实数据集中随机误差的效果，我们在生成y的时候，加上一些服从高斯分布随机误差："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[15.8144],\n",
      "        [15.7983],\n",
      "        [15.1210],\n",
      "        [15.3061],\n",
      "        [15.4152],\n",
      "        [15.5577],\n",
      "        [15.3078],\n",
      "        [15.8151],\n",
      "        [15.9422],\n",
      "        [15.4746]])\n"
     ]
    }
   ],
   "source": [
    "y = 0.5 * x + 15 + torch.rand(x.size())\n",
    "print(y[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在二维坐标轴上，这些点如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = torch.unsqueeze(torch.linspace(0, 10, 100), dim=1)\n",
    "y = 0.5 * x + 15 + torch.rand(x.size())\n",
    "\n",
    "plt.scatter(x.data.numpy(), y.data.numpy())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数据有了，我们可以开始搭建我们的模型了："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch[100/1000], loss:19.743334\n",
      "Epoch[200/1000], loss:7.338920\n",
      "Epoch[300/1000], loss:2.753949\n",
      "Epoch[400/1000], loss:1.059233\n",
      "Epoch[500/1000], loss:0.432826\n",
      "Epoch[600/1000], loss:0.201291\n",
      "Epoch[700/1000], loss:0.115709\n",
      "Epoch[800/1000], loss:0.084075\n",
      "Epoch[900/1000], loss:0.072383\n",
      "Epoch[1000/1000], loss:0.068061\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.5128]])\ttensor([15.3651])\n"
     ]
    }
   ],
   "source": [
    "class LinearRegression(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(LinearRegression, self).__init__()\n",
    "        self.linear = nn.Linear(1, 1)  # 因为是一元线性回归，所以输入和输出的维度都是1\n",
    "    def forward(self, x):\n",
    "        out = self.linear(x)\n",
    "        return out\n",
    "\n",
    "\n",
    "if torch.cuda.is_available():\n",
    "    model = LinearRegression().cuda()\n",
    "else:\n",
    "    model = LinearRegression()\n",
    "\n",
    "criterion = nn.MSELoss()  # 这里选择使用误差平方和作为损失函数，就是上文中说的函数J\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=1e-2)  # 定义梯度下降算法进行优化\n",
    "\n",
    "\n",
    "num_epochs = 1000  # 定义迭代次数\n",
    "for epoch in range(num_epochs):\n",
    "    if torch.cuda.is_available():\n",
    "        inputs = Variable(x).cuda()\n",
    "        target = Variable(y).cuda()\n",
    "    else:\n",
    "        inputs = Variable(x)\n",
    "        target = Variable(y)\n",
    "    # 向前传播\n",
    "    out = model(inputs)\n",
    "    loss = criterion(out, target)\n",
    "    # 向后传播\n",
    "    optimizer.zero_grad()  # 注意每次迭代都需要清零\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "    if (epoch + 1) % 100 == 0:\n",
    "        print('Epoch[{}/{}], loss:{:.6f}'.format(epoch + 1, num_epochs, loss.item()))\n",
    "model.eval()\n",
    "if torch.cuda.is_available():\n",
    "    predict = model(Variable(x).cuda())\n",
    "    predict = predict.data.cpu().numpy()\n",
    "else:\n",
    "    predict = model(Variable(x))\n",
    "    predict = predict.data.numpy()\n",
    "plt.plot(x.numpy(), y.numpy(), 'ro', label='Original Data')\n",
    "plt.plot(x.numpy(), predict, label='Fitting Line')\n",
    "plt.show()\n",
    "print(str(model.state_dict()['linear.weight']) + \"\\t\" + str(model.state_dict()['linear.bias']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4.2 TensorFlow2.0实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=205629, shape=(100,), dtype=float32, numpy=\n",
       "array([ 0.       ,  0.1010101,  0.2020202,  0.3030303,  0.4040404,\n",
       "        0.5050505,  0.6060606,  0.7070707,  0.8080808,  0.9090909,\n",
       "        1.010101 ,  1.111111 ,  1.2121212,  1.3131313,  1.4141414,\n",
       "        1.5151515,  1.6161616,  1.7171717,  1.8181818,  1.9191918,\n",
       "        2.020202 ,  2.121212 ,  2.222222 ,  2.3232322,  2.4242425,\n",
       "        2.5252526,  2.6262627,  2.7272727,  2.8282828,  2.929293 ,\n",
       "        3.030303 ,  3.131313 ,  3.2323232,  3.3333333,  3.4343433,\n",
       "        3.5353534,  3.6363635,  3.7373736,  3.8383837,  3.9393938,\n",
       "        4.040404 ,  4.141414 ,  4.242424 ,  4.3434343,  4.444444 ,\n",
       "        4.5454545,  4.6464643,  4.7474747,  4.848485 ,  4.949495 ,\n",
       "        5.050505 ,  5.151515 ,  5.2525253,  5.353535 ,  5.4545455,\n",
       "        5.5555553,  5.6565657,  5.7575755,  5.858586 ,  5.9595957,\n",
       "        6.060606 ,  6.161616 ,  6.262626 ,  6.363636 ,  6.4646463,\n",
       "        6.5656567,  6.6666665,  6.767677 ,  6.8686867,  6.969697 ,\n",
       "        7.070707 ,  7.171717 ,  7.272727 ,  7.3737373,  7.474747 ,\n",
       "        7.5757575,  7.6767673,  7.7777777,  7.8787875,  7.979798 ,\n",
       "        8.080808 ,  8.181818 ,  8.282828 ,  8.383839 ,  8.484848 ,\n",
       "        8.585858 ,  8.686869 ,  8.787879 ,  8.888888 ,  8.989899 ,\n",
       "        9.090909 ,  9.191919 ,  9.292929 ,  9.393939 ,  9.494949 ,\n",
       "        9.59596  ,  9.69697  ,  9.797979 ,  9.89899  , 10.       ],\n",
       "      dtype=float32)>"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = tf.linspace(0.,10.,100)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tf.Tensor(\n",
      "[16.014685  15.187728  16.314163  16.360064  16.853842  17.226461\n",
      " 15.9778385 16.685257  16.884115  16.397228 ], shape=(10,), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "y = 0.5 * x + 15 + tf.random.truncated_normal((100,), mean=1, stddev=0.5)\n",
    "print(y[:10])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAD4CAYAAAD1jb0+AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAaM0lEQVR4nO3dfYxcV3kG8OfJemkmRGSJbCIyJNiqiJGbCLvZtoEVJRhUpxARY0TAalFaUF1RoAmibjeoKOGvrDDlo0oFchMTokZuEHZNitu6KJtiYVWmaxw1cRw3CAjx2sSLwiaobJO1/faPmXFmx3PnnnvnnPv5/KRod+/enXuuMO+cee/7nkMzg4iIlM8FeQ9ARETSUQAXESkpBXARkZJSABcRKSkFcBGRklqW5cWWL19uK1euzPKSIiKld+jQoZ+b2Yre45kG8JUrV2JmZibLS4qIlB7Jp/sdVwpFRKSkFMBFREpKAVxEpKQUwEVESkoBXESkpBTARURKKtMyQhGROtlzeBbb9h3DifkFXD7WwNYNq7FxXdPb6yuAi4gEsOfwLG7f/RgWFs8AAGbnF3D77scAwFsQVwpFRCSAbfuOnQveHQuLZ7Bt3zFv11AAFxEJ4MT8QqLjaSiAi4gEcPlYI9HxNBTARURS2HN4FhNT01g1uRcTU9PYc3h2ye+3bliNxujIkmON0RFs3bDa2xj0EFNEKs93NYjLA8rOV1WhiIikFKIaZNADyu7X3Liu6TVg94pNoZC8guQjJJ8geYTkre3j72//fJbkeLARiogMIUQ1SBYPKF245MBPA/iUma0BcB2Aj5FcA+BxAJsA7A84PhGRoYQItlk8oHQRG8DN7KSZ/aD9/S8BHAXQNLOjZuavoFFEai/uwWAaIYJtvweURCs942vcLhJVoZBcCWAdgIMJ/mYLyRmSM3Nzc8lGJyK10clVz84vwPByrnrYYDioGiTtG8bGdU3ctekaNNtvAgRg7d/5GrcL5wBO8mIAuwDcZmYvuP6dmW03s3EzG1+x4rwt3UREAITrXOwOtgTQHGvgrk3XAMBQbxgb1zVxYHI9mmONc8Hb57hdOFWhkBxFK3g/YGa7ww5JROoo5IPBftUgE1PTTpUkcfJ8oOlShUIA9wI4amZfCD4iEamlrB8M+gq8eT7QdEmhTAD4EID1JB9t//cuku8leRzAmwHsJbkv6EhFpNKy6Fzs5ivwZj3ubrEpFDP7Hlo5+n7+ye9wRKSusuhc7LZ1w+olDT7A0oebruPIetzdaNabfg9nfHzcZmZmMrueiMgg/QI1gL6B/a5N12QSlPshecjMzmuYVCu9iNRWyIebWdBqhCIiXYrSJu9CM3ARkS6XjzUw2ydYuz7cDL0PZjfNwEVEugzTJh+qmzSKAriISJdh2uSz2AezmwK4iEiPtG3yWefPFcBFRCIkDchZd2UqgIuIREgakLPuylQAF5FSCbFmeJSkATlq5cNQVSgqIxSR0kiyv2XScr5B5yd5ndD7YHZTK72IlMbE1HTfGu3mWAMHJtef+7k30AOD2+Fdz8+yxrtbVCu9Uigi4lXIFIfrQ8Wk5Xwu52dd4+1CAVxEvAkd5FwfKiatHnE5nnWNtwsFcBHxJnSQc32omLR6xOV4EddIUQAXEW9CBznXKo+k1SMu5+e5804UVaGIiDfDLgTlwqXKI2n1iMv5gzaAyIuqUETEm6TVH2VTtCoUzcBFxJs8txfLQpY13i4UwEUklajZaNGCXJUpgItIYkk6IiUcBXARSWxQuWDSAO6SV84r91x0CuAikliackGXHeD7zeR9z/ar9GYQWwdO8gqSj5B8guQRkre2j19K8jskn2p/fXX44YpIESStiY7q0PzsPx+Jbfzx2RxUxHb4Ybg08pwG8CkzWwPgOgAfI7kGwCSAh83sDQAebv8sIjWQtFEmKgj/4leLfc/vnskPmu0nXXeliO3ww4hNoZjZSQAn29//kuRRAE0ANwG4vn3a1wH8B4C/CjJKEcmMS4ohablg0k7My8ca58YR1alySWM0cWqliO3ww0iUAye5EsA6AAcBXNYO7gDwMwCXRfzNFgBbAODKK69MO04RyUCSfHOScsGoDs2xxihePH32vMaft79xxXkNQd0aoyMgkfhBahadollyXguF5MUAdgG4zcxe6P6dtdo5+75Rmtl2Mxs3s/EVK1YMNVgRCSsqxXDbg48OtTRsVMrlzvf8Rt+1TR55ci4yeHfOmXdIv7iOI892+GE4zcBJjqIVvB8ws93tw8+SfK2ZnST5WgCnQg1SRMLqpCv6zU47hqn+iEu59L7eJx98tO/rEDi3cUPUeAfNpqvWKRobwEkSwL0AjprZF7p+9RCAWwBMtb9+K8gIRSSofuuXRElb6w34Sbl0B+e0i0tVqVPUZQY+AeBDAB4j2Xlb/DRagfsbJD8C4GkAN4cZooi4SFvf3C9tMsjs/AJWTe4dep/JQVyCc9Vm02m4VKF8D61PLv28w+9wRCSNYZpd0lRgdNdQR11j0JiAwYHXNThXaTadhjoxRSpgmNb2JBUivbprqHuDbdSY7nzoyJLXjXojqHtwdqEdeUQqYJj6ZtcKkSidANzb3Rj1QHR+YbFSzTR50gxcpAKGqW92rRCZmJrue40Rsm9AHiFxJsGGMWVtpsmTArhIBbhWZAyzhnfUNaJSLGfMzvt9Y3QEF45e0LeFvqzNNHlSABcpmUGVHf2Od9d4Ey933CWt6466RlQ9drPr94NWIATK3UyTJ+2JKVIiSfecdKnxbo41zjXHZDGmzt/UufwvKe2JKVIBSatNXGq8h809p6nHVoWJHwrgIiWStNrEJTj7yD0XISDXcVavMkKREkm6kUJccK5K7rlqGzW4UgAXKZGkq+n1O79T091Z1a8Ks9SqbdTgSikUkRJJmm+uy3ohVduowZUCuEjJJM03FyE/HVrVNmpwpRSKiJRe1TZqcKUZuIiUXl1SRb0UwEWkEuqQKuqlFIqISEkpgIuIlJQCuIhISSkHLhJIHVu7JVsK4CIBDLNHpYgrpVBEAqhra7dkSzNwkQDK0NqtFE/5KYCLBOC7tdt3sFWKpxqUQhEJIElr957Ds5iYmsaqyb2YmJo+bwnUEEulKsVTDbEzcJI7ANwI4JSZXd0+9iYAXwVwMYCfAPgDM3sh4DhFCivpHpW9fxs3E066C4+LMqR4JJ5LCuU+AHcDuL/r2D0A/sLMvkvywwC2AviM/+GJ5CsudREXgOMCrEtwDhFs67p6X9XEplDMbD+A53oOXwVgf/v77wB4n+dxieTOJXUxbCrCJTin3W1nkLqu3lc1aXPgRwDc1P7+/QCuiDqR5BaSMyRn5ubmUl5OJHsuwXnY2bFLcA4RbDeua+KuTdegOdYAUa3deeokbRXKhwH8LcnPAHgIwEtRJ5rZdgDbAWB8fNxSXk8kc4OCcye1EvUP2nV2vHXD6iUpGOD84BxqqdQ6rt5XNakCuJk9CeD3AIDkVQDe7XNQIkUQlSe+pDF6XtDtlmR27BqcFWyln1QBnORrzOwUyQsA/DVaFSkilRI1OyYRGbybKWbHwwRnNePUW2wOnOROAP8JYDXJ4yQ/AmAzyf8B8CSAEwC+FnaYItmLyhPP/2qx7/kEcGByfWYBNER9uJRL7AzczDZH/OrLnsciUjj9Zsfb9h0bugTPx8w5RH24lIs6MUUSGrYqxNfMWc04ogAuktCwJXi+2thD1IdLuWgxK5EUhnnw6Gvm7FKCKNWmGbhIxnzNnNWMI5qBi2TM58xZ9eH1pgAugmzrqUN1VnZTfXg9KIBL7eWxuUHUzNlH4NVmDfWhHLjUXlE2N/BVXliU+5HwFMCl9opST+0r8BblfiQ8pVAkc0XLzxZlcwNfgbco9yPhaQYumUqTJojbMzLp9XtfqyibG0QFWAMS3XdR7kfCUwCXTEWlCW578NHgG/pGvRaAQtRT9wu8HUnuW/Xh9UGz7PZYGB8ft5mZmcyuJ8WzanJv5CYIQGum2B1sJqam+6YDmmMNHJhcn+jaPl8rlE56qd84gWKNVbJD8pCZjfce1wxcMhWXh/W9ZRnwctokKigW6eHexnVNHJhcD0b8vkhjlfwpgEumBqUJOnxu6NudNomS5LV85eLjaKEqcaEALpnqzs9G8bmhb7+ce5rXynrzBD2IFBcqI5TMdboQezsGAf8b+g5KOSTZ/sx184SoEsmkpZNZtNtL+SmASyYGBbCQG/pG1UQnfRjokouPamGfefo57Do0m7i1XQtVSRwFcAkubm2OkEHK18p/Ls0xUbP0nQefwZmeai9tfSY+KAdeU1k+kMtzbQ5fNdEuOemoWXpv8I47X8SVZuA1lPVqdXmvzeFjlu+S7omapY+QfYO4KkpkWArgNZT1buZp1ubIc72UqGvHvRFEpWved21zSQ68c1wVJTIsBfAaynpGnDQPnfYTQt5raQ+apY+//lJVlIh3sQGc5A4ANwI4ZWZXt4+tBfBVABcCOA3gz8zs+yEHKv74Xq0uLnAmLYlL8wnBV1po2E8nUbN0VZRICC4z8PsA3A3g/q5jnwPwWTP7V5Lvav98vffRSRA+92R0DZxJAliaTwiDFsnatu+Y84w373y9SBKxVShmth/Ac72HAbyq/f0lAE54HpcE5HO1uhAVJmnayAcF2CRdk2phlzJJmwO/DcA+kp9H603gLVEnktwCYAsAXHnllSkvJ775+kgfYsaa5hNCVFqowzUN4vPTiUhoaQP4RwF80sx2kbwZwL0A3tnvRDPbDmA70FpONuX1JCdx+e2owNnZhCDNwzrXnHn32C5pjGJ0hFg8E/1PrPdNZZjuUJEicFoPnORKAN/ueoj5PIAxMzOSBPC8mb1qwEsA0HrgZRO1Vkl3uqXfOd16zw85ttELiIsvXIZf/Gqx7990t8+73JtIUfheD/wEgLe1v18P4Km0A5Picslvx60uGKrjst/YFs8aLnrFMnzpA2tjuya1c7tUgUsZ4U60KkyWkzwO4A4AfwLgyySXAfg/tHPcUi2u+e1OPj1qt50QFRyDxuaSBlG1iVRBbAA3s80Rv7rW81ikYJLWi2e5G3rcteIe0mrndqkCLWYlkZJuKpDlJgTDXksbJkgVqJVeIiWtyMiygmPYa6naRKpAu9KLiBRcVBWKZuDiLM8VAkXkfArg4iTrNcQHjUNvIiItCuDiFBSzXkM8apxFeBMRKQoF8IwUdeboGhSLUDddhDcRkSJRGWEGOkFydn4BhmSr44Xm2pFYhFX6ivAmIlIkmoFnYNiZo6/Ze7/XcQ2KRVilT803IktpBp6BYWaOvmbvUa8zdtFo3/N7g6LPNcTTUvONyFKagWdgmJmjr7xv1Ov82rIL0BgdcZpZJ11D3HfeX803IkspgGdgmPSDr7xv1PnPLyziix9Y6z0ohqoY0d6SIi9TAM/AMDNHX3nfQa8TIiiqYkQkPAXwjKQNkr4eHmb9EFIVIyLhKYAXnK+8b9b54zSfHIpaKy9SVFrMSoJIumWZtjgTiVbbxayqNqsry/0knfErZy6SXKVn4FWb1fW7H6K1A3yzwMHcRdR2bATw46l3Zz0ckULxvalxKVRt49p+99MJekVqz0+jCK36ImVT6QBetUqIuHGX+c1JXZYiyVU6gFdtVucy7rK+ORWhVV+kbCr9ELMICzD51O9+epX1zQlQl6VIUpUO4FVbO6P7fmbnF849wOwgWrnwianpc/cZqmqlLNUwIlUWW4VCcgeAGwGcMrOr28ceBNCZxo4BmDeztXEXUx24X50g2i+YN0ZH8L5rm9h1aDZxFU5ccK5adY9I0Q1ThXIfgBu6D5jZB8xsbTto7wKw28soJZGN65o4MLkezbHGeSV4C4tnsPPgM4mrcFyWr61adY9IWcUGcDPbD+C5fr8jSQA3A9jpeVySQNSDyzMRn64GPeh0Cc5Vq+4RKathq1DeCuBZM3vKx2AknagHlyNkovMBt+BcteoekbIaNoBvRszsm+QWkjMkZ+bm5oa8XBh7Ds9iYmoaqyb3YmJqunTNMFE11Jt/54rEtdUuwVk12yLFkLoKheQyAJsAXDvoPDPbDmA70HqImfZ6SSSpkAi18UCWBlXbjL/+0kTVIi6ll1Wr7hEpK6e1UEiuBPDtThVK+9gNAG43s7e5XiyLKpSkFRITU9N9lz1tjjVwYHJ9sDEWOfgVfXwidZN6NUKSOwFcD2A5yeMA7jCzewF8EAV8eJl0VTufD+RcAt+gGX9n/HkHTjXUiJRDbAA3s80Rx//I+2g8SBqQXTceSFobHZWKiXqDufOhI3jx9NlSp3JEJFuVWwslaYWEywM5n7XRUW8k8wuL3mqry/5QVkTcVC6AJ62QcFlEyWdtdNJSu6SpHJc3GxGphsqtheJaIZHkQZ1rbbRLKsZlQapBfx9HO9uI1EflAjgQ/xAuaemgS3B2Xfmwd0GqQdLUVqtLUqQ+KpdCcZF0LQ+XtEyS9aw7a5j075NsSbsetrokReqjkjPwOElnqa5pmaTld1Ez+2Fq0Ku2BrqIRKtlAHfNV3cLURsdItiqS1KkPmoZwIsySw0VbNWII1IPtQzgRZqlKtiKSFq1DOCAv8CpdUNEJC+1DeA+VGElQxEpLwXwHklm1GqaEZE8VSaA+0hluM6ouzcT7kdNMyKShUo08vha/8Olwaf7WlHUNCMiWSj1DHzQTDhNKsOlwadfkO+mphkRyUppA3i/nXd6JU1lRDX4GFo792zdsHrgazY9VqGoukVE4pQ2hRI3EwaSpzL6rXnS0UnLjF002vf3nfZ3X8FbS8KKSJzSBvC42XWaVEb3glT9LCyegRmC78iedLEtEamn0gbwQbPrtCv5AfErBT6/sOi86mBaWhJWRFyUNgcetZ6Jr2A6aMGr0O3vaRbbEpH6Ke0MPMn622kk3ZrNpzyvLSLlUdoZOBB2Iag8F7wq0mJbIlJcNLPMLjY+Pm4zMzOZXU9EpApIHjKz8d7jpU2hiIjUXWwAJ7mD5CmSj/cc/wTJJ0keIfm5UAPcc3gWE1PTWDW5FxNT06qFFhFpc8mB3wfgbgD3dw6QfDuAmwC8ycxeJPmaEIPzvVyruhtFpEpiA7iZ7Se5sufwRwFMmdmL7XNO+R+a3+Vas167W28WIhJa2hz4VQDeSvIgye+S/K2oE0luITlDcmZubi7RRXw2tGTZ3ahWeBHJQtoAvgzApQCuA7AVwDdI9m1eNLPtZjZuZuMrVqxIdJGoxpU0DS1ZdjeqFV5EspA2gB8HsNtavg/gLIDl/obV4rOhxeebQRy1wotIFtIG8D0A3g4AJK8C8AoAP/c1qA6f3ZZZdjdm+WYhIvUV+xCT5E4A1wNYTvI4gDsA7ACwo11a+BKAWyxQR5Cvbsssuxuj1mlRK7yI+KROzEBUhSIivkR1YpZ6LZQiC71ioYiIWulFREpKAVxEpKQUwEVESkoBXESkpBTARURKSgFcRKSkFMBFREpKAVxEpKQUwEVESkoBXESkpBTARURKSgFcRKSkFMBFREpKAVxEpKQUwEVESkoBXESkpEq3oYN2uhERaSlVAN9zeHbJXpOz8wu4ffdjAKAgLiK1U6oUyrZ9x5ZsFAwAC4tnsG3fsZxGJCKSn1IF8BPzC4mOi4hUWakC+OVjjUTHRUSqrFQBfOuG1WiMjiw51hgdwdYNq3MakYhIfmIDOMkdJE+RfLzr2J0kZ0k+2v7vXWGH2bJxXRN3bboGzbEGCKA51sBdm67RA0wRqSWXKpT7ANwN4P6e4180s897H1GMjeuaCtgiInCYgZvZfgDPZTAWERFJYJgc+MdJ/nc7xfJqbyMSEREnaQP4VwD8OoC1AE4C+JuoE0luITlDcmZubi7l5UREpFeqAG5mz5rZGTM7C+DvAfz2gHO3m9m4mY2vWLEi7ThFRKRHqgBO8rVdP74XwONR54qISBixVSgkdwK4HsBykscB3AHgepJrARiAnwD404BjFBGRPmhm2V2MnAPwdMo/Xw7g5x6HUwa653qo2z3X7X6B4e/59WZ2Xg460wA+DJIzZjae9ziypHuuh7rdc93uFwh3z6VqpRcRkZcpgIuIlFSZAvj2vAeQA91zPdTtnut2v0Cgey5NDlxERJYq0wxcRES6KICLiJRUKQI4yRtIHiP5Q5KTeY8nNJJXkHyE5BMkj5C8Ne8xZYHkCMnDJL+d91iyQHKM5DdJPknyKMk35z2m0Eh+sv1v+nGSO0lemPeYfIvYQ+FSkt8h+VT7q5cFAAsfwEmOAPg7AL8PYA2AzSTX5Duq4E4D+JSZrQFwHYCP1eCeAeBWAEfzHkSGvgzg38zsjQDehIrfO8kmgD8HMG5mVwMYAfDBfEcVxH0Abug5NgngYTN7A4CH2z8PrfABHK2Fsn5oZj8ys5cA/COAm3IeU1BmdtLMftD+/pdo/R+70rtYkHwdgHcDuCfvsWSB5CUAfhfAvQBgZi+Z2Xy+o8rEMgANkssAXATgRM7j8S5iD4WbAHy9/f3XAWz0ca0yBPAmgGe6fj6OigezbiRXAlgH4GC+IwnuSwD+EsDZvAeSkVUA5gB8rZ02uofkK/MeVEhmNgvg8wB+itYy1M+b2b/nO6rMXGZmJ9vf/wzAZT5etAwBvLZIXgxgF4DbzOyFvMcTCskbAZwys0N5jyVDywD8JoCvmNk6AP8LTx+ri6qd970JrTevywG8kuQf5juq7FmrdttL/XYZAvgsgCu6fn5d+1ilkRxFK3g/YGa78x5PYBMA3kPyJ2ilyNaT/Id8hxTccQDHzazzyeqbaAX0KnsngB+b2ZyZLQLYDeAtOY8pK892luFufz3l40XLEMD/C8AbSK4i+Qq0Hno8lPOYgiJJtHKjR83sC3mPJzQzu93MXmdmK9H633fazCo9MzOznwF4huTq9qF3AHgixyFl4acAriN5Ufvf+DtQ8Qe3XR4CcEv7+1sAfMvHi7rsSp8rMztN8uMA9qH11HqHmR3JeVihTQD4EIDHSD7aPvZpM/uXHMck/n0CwAPticmPAPxxzuMJyswOkvwmgB+gVWl1GBVsq4/YQ2EKwDdIfgStJbVv9nIttdKLiJRTGVIoIiLShwK4iEhJKYCLiJSUAriISEkpgIuIlJQCuIhISSmAi4iU1P8DLGTz9oQPR1QAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.scatter(x.numpy(), y.numpy())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "# 模型中的两个参数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch : 0    loss: tf.Tensor(292.91647, shape=(), dtype=float32)    w: 1.7383862    b: 2.0522277\n",
      "epoch : 100    loss: tf.Tensor(18.258339, shape=(), dtype=float32)    w: 1.7545552    b: 7.595278\n",
      "epoch : 200    loss: tf.Tensor(6.849392, shape=(), dtype=float32)    w: 1.2592618    b: 10.889324\n",
      "epoch : 300    loss: tf.Tensor(2.6323707, shape=(), dtype=float32)    w: 0.95813954    b: 12.891996\n",
      "epoch : 400    loss: tf.Tensor(1.0736642, shape=(), dtype=float32)    w: 0.7750678    b: 14.109551\n",
      "epoch : 500    loss: tf.Tensor(0.4975283, shape=(), dtype=float32)    w: 0.66376615    b: 14.849785\n",
      "epoch : 600    loss: tf.Tensor(0.28457418, shape=(), dtype=float32)    w: 0.5960984    b: 15.299823\n",
      "epoch : 700    loss: tf.Tensor(0.20585985, shape=(), dtype=float32)    w: 0.5549578    b: 15.573437\n",
      "epoch : 800    loss: tf.Tensor(0.17676613, shape=(), dtype=float32)    w: 0.5299465    b: 15.7397785\n",
      "epoch : 900    loss: tf.Tensor(0.16601223, shape=(), dtype=float32)    w: 0.5147401    b: 15.840912\n",
      "last weight w=0.5055667161941528 and b=15.901921272277832\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    " \n",
    "\n",
    "w = tf.Variable(np.random.randn(), name=\"weight\")\n",
    "b = tf.Variable(np.random.randn(), name=\"bias\")\n",
    "\n",
    "learning_rate = 0.01  # 学习率\n",
    "# 所有样本训练的次数\n",
    "epoch_number = 1000  # 迭代次数\n",
    "optimizer = tf.optimizers.SGD(learning_rate)  #优化器\n",
    "# 开始训练\n",
    "for epoch in range(epoch_number):\n",
    "    with tf.GradientTape() as g:\n",
    "        pred = w*x + b\n",
    "        loss = tf.losses.MSE(pred, y)  # 计算均方差损失\n",
    "    # 计算梯度\n",
    "    gradients = g.gradient(loss, [w, b])\n",
    "    # 更新参数\n",
    "    optimizer.apply_gradients(zip(gradients, [w, b]))\n",
    "\n",
    "    if epoch % 100 == 0:\n",
    "        print('epoch :',epoch, '   loss:', loss, '   w:', w.numpy(), '   b:', b.numpy())\n",
    "# 对所有样本迭代完1000次后 输出最后的w,b\n",
    "print('last weight w={0} and b={1}'.format(w.numpy(),b.numpy()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(x.numpy(), y.numpy(), 'ro')\n",
    "plt.plot(x.numpy(), w.numpy()*x+b.numpy())\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "tensorflow_gpu",
   "language": "python",
   "name": "tensorflow_gpu"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
